home *** CD-ROM | disk | FTP | other *** search
/ PsL Monthly 1993 December / PSL Monthly Shareware CD-ROM (December 1993).iso / prgmming / dos / pascal / miscuni.com / STACKS.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1989-05-23  |  5.8 KB  |  162 lines

  1. {.he Stack Maintenance Module - %F}
  2. (********************************************************************)
  3. (*                             Stacks                               *)
  4. (*                                                                  *)
  5. (*  Author: Geoff Moehrke                                           *)
  6. (*  Date: August 27, 1988                                           *)
  7. (*                                                                  *)
  8. (*  Purpose: Stack implementation, allows stacking of any data type *)
  9. (*           using Turbo Pascal's generic pointers to reference     *)
  10. (*           stacked data.                                          *)
  11. (*                                                                  *)
  12. (*  Source: F:\TP\UNIT\STACKS.PAS                                   *)
  13. (********************************************************************)
  14. Unit Stacks;
  15.  
  16. interface
  17.  
  18. type
  19.   StackPtr = ^StackRec;
  20.   StackRec = record
  21.                Data: Pointer;   { Generic pointer to data  }
  22.                Next: StackPtr;  { Pointer to next StackRec }
  23.              end;
  24.  
  25.   Stack = record
  26.              DataSize : Word;   { Size of data in this queue          }
  27.              Top : StackPtr;    { Pointer to top of stack             }
  28.              Height,            { Current Height of stack             }
  29.              MaxHeight : Word;  { Maximum length stack reached so far }
  30.            end;
  31.  
  32.  procedure InitStack (Var S: Stack; Size: Word );
  33.    {- Initialize stack variables and set up for processing.          }
  34.    {  Must be called for each stack before performing any operations }
  35.    {  on it.                                                         }
  36.    {  Example: InitStack ( MyStack, SizeOf(MyType) );                }
  37.  
  38.  
  39.  function Push(Var S:Stack; Item: Pointer) : boolean;
  40.    {- Push Item onto stack S.  Returns True if successful, false     }
  41.    {  if insufficient memory.                                        }
  42.    {                                                                 }
  43.    {  Parameters:  S - stack variable                                }
  44.    {               Item - generic pointer to item.  easiest way is   }
  45.    {                      to use address operator (@AnyVar)          }
  46.    {                                                                 }
  47.    {  Example: if Push( MyStack, @MyVar) then                        }
  48.    {              ...                                                }
  49.  
  50.  function Pop(Var S: Stack):Pointer;
  51.    {- Pops top item off stack, returns a pointer to it, nil if       }
  52.    {  stack is empty.                                                }
  53.    {                                                                 }
  54.    {  Easiest way to access data after popping it is to use          }
  55.    {  typecasting to a pointer to the data type being stacked.       }
  56.    {  Example:                                                       }
  57.    {                                                                 }
  58.    {            If Not StackEmpty(MyStack) then                      }
  59.    {               IntVar := Integer( Pop(MyStack)^ );               }
  60.    {                                                                 }
  61.    {                                                                 }
  62.    {  Where: IntPtr is defined as ^Integer & NumP is of type IntPtr. }
  63.    {  Note that in this method the check for StackEmpty is           }
  64.    {  necessary to prevent Pop(MyStack) from accessing a nil pointer.}
  65.  
  66.  function StackEmpty(S: Stack):Boolean;
  67.    {- determine whether stack is empty or not }
  68.  
  69.  function StackSize(S: Stack):Word;
  70.    {- returns current size (height) of stack S }
  71.  
  72.  function MaxStackSize(S: Stack):Word;
  73.    {- ruturns the maximum size (height) that S has reached  }
  74.  
  75. implementation
  76.  
  77.  procedure InitStack(Var S: Stack; Size: Word);
  78.    {- Initialize stack variables and set up for processing }
  79.  
  80.    begin
  81.      with S do begin
  82.        Top := nil;
  83.        DataSize := Size;
  84.        Height := 0;
  85.        MaxHeight := 0;
  86.      end;
  87.    end;
  88.  
  89.  {$F+}
  90.  function HeapFunc( Size : Word ): Integer;
  91.    { Prevent New() or GetMem() from causing a run-time error if
  92.      memory not available (see TP Manual - Chapter 15).        }
  93.  
  94.    begin
  95.      HeapFunc := 1;
  96.    end;
  97.  {$F-}
  98.  
  99.  function Push(Var S:Stack; Item: Pointer): boolean;
  100.    {- Push Item onto stack S, returns false if not enough heap space }
  101.  
  102.    var NewItem, Temp:StackPtr;
  103.  
  104.    begin
  105.      Push := False;
  106.      New(NewItem);
  107.      If NewItem = nil then
  108.        Exit;                { Not enough memory }
  109.      GetMem(NewItem^.Data,S.DataSize);
  110.      If NewItem^.Data = nil then
  111.        Exit;
  112.      Move(Item^,NewItem^.Data^,S.DataSize);
  113.      With S do begin
  114.        Temp := Top;
  115.        Top := NewItem;         { add new item at end }
  116.        Top^.Next := Temp;
  117.        inc(Height);             { increment the height }
  118.        if Height > MaxHeight then  { adjust max height }
  119.          MaxHeight := Height;
  120.        Push := True;
  121.      end
  122.    end;
  123.  
  124.  function Pop(Var S: Stack):Pointer;
  125.    {- Returns a pointer item popped from S, nil if stack is empty }
  126.  
  127.    var Temp : StackPtr;
  128.  
  129.    begin
  130.      Pop := nil;
  131.      if S.Height = 0 then  { stack is empty - exit w/nil pointer }
  132.        exit;
  133.      with S do begin
  134.        Dec(Height);
  135.        Pop := Top^.Data;
  136.        Top := Top^.Next;
  137.      end;
  138.    end;
  139.  
  140.  function StackEmpty(S: Stack):Boolean;
  141.    {- determine whether stack S is empty or not }
  142.  
  143.    begin
  144.      StackEmpty := S.Height = 0;
  145.    end;
  146.  
  147.  function StackSize(S: Stack):Word;
  148.    {- returns current size of stack }
  149.  
  150.    begin
  151.      StackSize := S.Height;
  152.    end;
  153.  
  154.  function MaxStackSize(S: Stack):Word;
  155.    {- returns maximum height stack S has reached }
  156.  
  157.    begin
  158.      MaxStackSize := S.MaxHeight;
  159.    end;
  160.  
  161.  
  162. end. { Unit Stacks }